﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Web.Mvc;
using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.ICM;
using KPIS.GERP.Models.SYS;

namespace KPIS.GERP.WCF.SYS
{
	[ServiceContract]
	public interface ISysMasterService
	{
        [OperationContract]
        string GenNewRefNo(string table, string prefix, int? year, int? month);

        [OperationContract]
        string GenNewRefNo2(string table, string prefix, int? year, int? month, int? day);

	    [OperationContract]
	    IEnumerable<MenuItemsList> SelectMenuItemList(MenuItemsList criteriaModel, List<string> includeSubObjectString = null);
            #region YearType
		[OperationContract]
		IEnumerable<YearType> SelectYearType(YearType criteriaModel = null, List<string> includeSubObjectString = null);

		[OperationContract]
		IList<SelectListItem> SelectListYearType(YearType criteriaModel = null);

		[OperationContract]
		IList<SelectListItem> SelectListGenerateRangeYear(int beforeCurrentYear, int afterCurrentYear, bool insertBlankAtFirst = false);

		[OperationContract]
		int InsertYearType(YearType model, int createByUserId);

		[OperationContract]
		void UpdateYearType(YearType model, int updateByUserId);

		[OperationContract]
		void DeleteYearType(int id, int deleteByUserId);
		#endregion
	}

	[ServiceErrorBehavior(typeof(ElmahErrorHandler))]
	public class SysMasterService : ISysMasterService
	{

        public string GenNewRefNo(string table, string prefix, int? year, int? month)
        {
            try
            {                
                year = year.HasValue ? year : DateTime.Now.Year;
                month = month.HasValue ? month : DateTime.Now.Month;

                var culture = new System.Globalization.CultureInfo("th-TH");
                var dateValue = new DateTime((int)year, (int)month, DateTime.Now.Day);

                int cnt = 0;
                string sql = "SELECT COUNT(*) as cnt FROM " + table + " WHERE YEAR(created_when) = " + year + " AND MONTH(created_when) = " + month;
              
                using (var context = new GERPContext(false))
                {
                    var lst = context.Database.SqlQuery<int>(sql).ToList();
                    cnt = lst.FirstOrDefault();                    
                    //int cnt = query.Where(a => a.CreatedWhen.Value.Year == year && a.CreatedWhen.Value.Month == month).OrderByDescending(a => a.PrId).Count();
                    string data = prefix.ToUpper() + "-" + dateValue.ToString("yyyy", culture) + dateValue.ToString("MM", culture) + "-" + (cnt + 1).ToString("0000");
                    return data;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string GenNewRefNo2(string table, string prefix, int? year, int? month, int? day)
        {
            try
            {
                //string strCodeDate = DateTime.Today.Year.ToString("0000").Substring(DateTime.Today.Year.ToString("0000").Length - 2)
                //+ DateTime.Today.Month.ToString("00") + DateTime.Today.Day.ToString("00");

                year = year.HasValue ? year : DateTime.Now.Year;
                month = month.HasValue ? month : DateTime.Now.Month;
                day = day.HasValue ? day : DateTime.Now.Day;

                var culture = new System.Globalization.CultureInfo("th-TH");
                var dateValue = new DateTime((int)year, (int)month, (int)day);

                string strCodeDate = dateValue.ToString("yy", culture) + dateValue.ToString("MM", culture) + dateValue.ToString("dd", culture);

                int cnt = 0;
                string sql = "SELECT Max(ref_no) as max FROM " + table 
                    + " WHERE YEAR(created_when) = " + year + " AND MONTH(created_when) = " 
                    + month + " AND Day(created_when) = " + day;

                using (var context = new GERPContext(false))
                {
                    var lst = context.Database.SqlQuery<string>(sql);
                    if (lst != null)
                    {
                        string max = lst.FirstOrDefault();
                        max = max.Substring(max.Length - 4, 4);
                        cnt = Convert.ToInt32(max) + 1;
                    }
                    else {
                        cnt = 1;
                    }
                    //int cnt = query.Where(a => a.CreatedWhen.Value.Year == year && a.CreatedWhen.Value.Month == month).OrderByDescending(a => a.PrId).Count();
                    string data = prefix.ToUpper() + strCodeDate + cnt.ToString("0000");
                    return data;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

	    public IEnumerable<MenuItemsList> SelectMenuItemList(MenuItemsList criteriaModel, List<string> includeSubObjectString = null)
	    {
			try
			{
				using (var context = new GERPContext(false))
				{
					IQueryable<MenuItemsList> query = context.MenuItemsLists;

					if (includeSubObjectString != null)
					{
						query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
					}

					if (criteriaModel != null)
					{
						object[] param;
						query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
					}

					var x = query.ToList();
					return x;
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
	    }

	    #region Implementation of ISysMasterService

		public IEnumerable<YearType> SelectYearType(YearType criteriaModel = null, List<string> includeSubObjectString = null)
		{
			try
			{
				using (var context = new GERPContext(false))
				{
					IQueryable<YearType> query = context.YearTypes;

					if (includeSubObjectString != null)
					{
						query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
					}

					if (criteriaModel != null)
					{
						object[] param;
						query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
					}

					var x = query.ToList();
					return x;
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public IList<SelectListItem> SelectListYearType(YearType criteriaModel = null)
		{
			var list = new List<SelectListItem>();

			try
			{
				using (var context = new GERPContext(false))
				{
					IQueryable<YearType> query = context.YearTypes;

					if (criteriaModel != null)
					{
						object[] param;
						query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
					}

					var x = query.ToList();
					foreach (var MasUnit in x)
					{
						var item = new SelectListItem { Text = MasUnit.YearTypeName, Value = MasUnit.YearTypeId.ToString() };
						list.Add(item);
					}
				}

			}
			catch (Exception ex)
			{
				throw ex;
			}

			return list;
		}

		public IList<SelectListItem> SelectListGenerateRangeYear(int beforeCurrentYear, int afterCurrentYear, bool insertBlankAtFirst = false)
		{
			var result = new List<SelectListItem>();
			for (int i = Utility.BuddishYear - beforeCurrentYear; i <= Utility.BuddishYear + afterCurrentYear; i++)
			{
				result.Add(new SelectListItem {Text = i.ToString(), Value = i.ToString()});
			}
			return result;
		}

		public int InsertYearType(YearType model, int createByUserId)
		{
			try
			{
				using (var context = new GERPContext())
				{
					model.RecordStatus = RecordStatus.UsedStatus;
					model.UpdatedBy = createByUserId;
					model.UpdatedWhen = DateTime.Now;
					context.YearTypes.Add(model);
					context.SaveChanges();

					return model.YearTypeId;
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public void UpdateYearType(YearType model, int updateByUserId)
		{
			try
			{
				using (var context = new GERPContext())
				{
					context.Entry(model).State = EntityState.Modified;
					model.UpdatedBy = updateByUserId;
					model.UpdatedWhen = DateTime.Now;
					context.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public void DeleteYearType(int id, int deleteByUserId)
		{
			try
			{
				using (var context = new GERPContext())
				{
					var modelToDelete = context.YearTypes.Find(id);
					if (modelToDelete == null) return;

					context.Entry(modelToDelete).State = EntityState.Modified;
					modelToDelete.RecordStatus = RecordStatus.DeletedStatus;
					modelToDelete.UpdatedBy = deleteByUserId;
					modelToDelete.UpdatedWhen = DateTime.Now;
					context.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		#endregion
	}
}
